/home/emellor/log2
authoremellor@ewan <emellor@ewan>
Sun, 9 Oct 2005 11:14:46 +0000 (12:14 +0100)
committeremellor@ewan <emellor@ewan>
Sun, 9 Oct 2005 11:14:46 +0000 (12:14 +0100)
tools/python/xen/util/asserts.py [new file with mode: 0644]
tools/python/xen/xend/XendClient.py
tools/python/xen/xend/XendDomain.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/server/SrvDomain.py
tools/python/xen/xend/server/SrvDomainDir.py
tools/python/xen/xm/main.py

diff --git a/tools/python/xen/util/asserts.py b/tools/python/xen/util/asserts.py
new file mode 100644 (file)
index 0000000..78f4c1b
--- /dev/null
@@ -0,0 +1,22 @@
+#===========================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2005 XenSource Ltd
+#============================================================================
+
+
+def isCharConvertible(c):
+    assert (isinstance(c, int) or
+            (isinstance(c, str) and
+             len(c) == 1)), "%s is not convertible to a character" % c
index 5f198ac9f7b6b8626e66fc00d9535ca6423a5c63..39c57dc8b88032dbc2d42020d155924dd617d112 100644 (file)
@@ -196,6 +196,9 @@ class Xend:
     def xend_domains(self):
         return self.xendGet(self.domainurl())
 
+    def xend_list_domains(self):
+        return self.xendGet(self.domainurl(), {'detail': '1'})
+
     def xend_domain_create(self, conf):
         return self.xendPost(self.domainurl(),
                              {'op'      : 'create',
index 56e967dfb76240e2ea31f88efc9da716d97dbdf2..7809c80fd9036f5c86799614d6b8802415785cd2 100644 (file)
@@ -359,20 +359,6 @@ class XendDomain:
             raise XendError(str(ex))
 
 
-    def domain_shutdown(self, domid, reason = 'poweroff'):
-        """Shutdown domain (nicely).
-
-        @param reason: shutdown reason: poweroff, reboot, suspend, halt
-        """
-        self.callInfo(domid, XendDomainInfo.XendDomainInfo.shutdown, reason)
-
-
-    def domain_sysrq(self, domid, key):
-        """Send a SysRq to the specified domain."""
-        return self.callInfo(domid, XendDomainInfo.XendDomainInfo.send_sysrq,
-                             key)
-
-
     def domain_destroy(self, domid):
         """Terminate domain immediately."""
 
@@ -475,37 +461,6 @@ class XendDomain:
             raise XendError(str(ex))
 
 
-    def domain_device_create(self, domid, devconfig):
-        """Create a new device for the specified domain.
-        """
-        return self.callInfo(domid,
-                             XendDomainInfo.XendDomainInfo.device_create,
-                             devconfig)
-
-
-    def domain_device_configure(self, domid, devconfig, devid):
-        """Configure an existing device in the specified domain.
-        @return: updated device configuration
-        """
-        return self.callInfo(domid,
-                             XendDomainInfo.XendDomainInfo.device_configure,
-                             devconfig, devid)
-
-    
-    def domain_device_destroy(self, domid, devtype, devid):
-        """Destroy a device."""
-        return self.callInfo(domid,
-                             XendDomainInfo.XendDomainInfo.destroyDevice,
-                             devtype, devid)
-
-
-    def domain_devtype_ls(self, domid, devtype):
-        """Get list of device sxprs for the specified domain."""
-        return self.callInfo(domid,
-                             XendDomainInfo.XendDomainInfo.getDeviceSxprs,
-                             devtype)
-
-
     def domain_vif_limit_set(self, domid, vif, credit, period):
         """Limit the vif's transmission rate
         """
@@ -537,44 +492,6 @@ class XendDomain:
         except Exception, ex:
             raise XendError(str(ex))
 
-    def domain_mem_target_set(self, domid, mem):
-        """Set the memory target for a domain.
-
-        @param mem: memory target (in MiB)
-        """
-        self.callInfo(domid, XendDomainInfo.XendDomainInfo.setMemoryTarget,
-                      mem << 10)
-
-
-    def domain_vcpu_hotplug(self, domid, vcpu, state):
-        """Enable or disable specified VCPU in specified domain
-
-        @param vcpu: target VCPU in domain
-        @param state: which state VCPU will become
-        """
-        self.callInfo(domid, XendDomainInfo.XendDomainInfo.vcpu_hotplug, vcpu,
-                      state)
-
-
-    def domain_dumpcore(self, domid):
-        """Save a core dump for a crashed domain."""
-        self.callInfo(domid, XendDomainInfo.XendDomainInfo.dumpCore)
-
-
-    ## private:
-
-    def callInfo(self, domid, fn, *args, **kwargs):
-        try:
-            self.refresh()
-            dominfo = self.domains.get(domid)
-            if dominfo:
-                return fn(dominfo, *args, **kwargs)
-        except XendError:
-            raise
-        except Exception, exn:
-            log.exception("")
-            raise XendError(str(exn))
-
 
 def instance():
     """Singleton constructor. Use this instead of the class constructor.
index 2b3bf0666700a58310805160076170a69b3d7994..e8ed2c29957bde2abb42481553c922c0d0324743 100644 (file)
@@ -30,6 +30,7 @@ import threading
 import errno
 
 import xen.lowlevel.xc
+from xen.util import asserts
 from xen.util.blkif import blkdev_uname_to_file
 
 from xen.xend import image
@@ -41,7 +42,8 @@ from xen.xend.XendLogging import log
 from xen.xend.XendError import XendError, VmError
 from xen.xend.XendRoot import get_component
 
-from xen.xend.uuid import getUuid
+from uuid import getUuid
+
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
 
@@ -793,10 +795,12 @@ class XendDomainInfo:
 
     def setMemoryTarget(self, target):
         """Set the memory target of this domain.
-        @param target In KiB.
+        @param target In MiB.
         """
-        self.info['memory_KiB'] = target
-        self.storeDom("memory/target", target)
+        # Internally we use KiB, but the command interface uses MiB.
+        t = target << 10
+        self.info['memory_KiB'] = t
+        self.storeDom("memory/target", t)
 
 
     def update(self, info = None):
@@ -1366,7 +1370,10 @@ class XendDomainInfo:
         self.storeVm('vcpu_avail', self.info['vcpu_avail'])
         self.storeDom("cpu/%d/availability" % vcpu, availability)
 
-    def send_sysrq(self, key=0):
+
+    def send_sysrq(self, key):
+        asserts.isCharConvertible(key)
+
         self.storeDom("control/sysrq", '%c' % key)
 
 
index 8c70bfe27d3f7206e4db0237848acaac5c9894bf..7dd7d16da477047c21e109e8a87ae80c6f8065b3 100644 (file)
@@ -51,40 +51,28 @@ class SrvDomain(SrvDir):
         val = self.xd.domain_pause(self.dom.domid)
         return val
 
-    def op_shutdown(self, op, req):
-        fn = FormFn(self.xd.domain_shutdown,
-                    [['dom',    'int'],
-                     ['reason', 'str']])
-        val = fn(req.args, {'dom': self.dom.domid})
+    def acceptCommand(self, req):
         req.setResponseCode(http.ACCEPTED)
         req.setHeader("Location", "%s/.." % req.prePathURL())
-        return val
+
+    def op_shutdown(self, op, req):
+        self.acceptCommand(req)
+        return self.dom.shutdown(req.args['reason'][0])
 
     def op_sysrq(self, op, req):
-        fn = FormFn(self.xd.domain_sysrq,
-                    [['dom',    'int'],
-                     ['key',    'int']])
-        val = fn(req.args, {'dom' : self.dom.domid})
-        req.setResponseCode(http.ACCEPTED)
-        req.setHeader("Location", "%s/.." % req.prePathURL())
-        return val
+        self.acceptCommand(req)
+        return self.dom.send_sysrq(int(req.args['key'][0]))
 
     def op_destroy(self, op, req):
-        fn = FormFn(self.xd.domain_destroy,
-                    [['dom',    'int']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        req.setHeader("Location", "%s/.." % req.prePathURL())
-        return val
+        self.acceptCommand(req)
+        return self.xd.domain_destroy(self.dom.domid)
 
     def op_save(self, op, req):
+        self.acceptCommand(req)
         return req.threadRequest(self.do_save, op, req)
 
     def do_save(self, op, req):
-        fn = FormFn(self.xd.domain_save,
-                    [['dom',  'int'],
-                     ['file', 'str']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return 0
+        return self.xd.domain_save(self.dom.domid, req.args['file'][0])
 
     def op_migrate(self, op, req):
         return req.threadRequest(self.do_migrate, op, req)
@@ -134,43 +122,39 @@ class SrvDomain(SrvDir):
                      ['memory', 'int']])
         val = fn(req.args, {'dom': self.dom.domid})
         return val
+
     
+    def call(self, fn, args, req):
+        return FormFn(fn, args)(req.args)
+
+
     def op_mem_target_set(self, op, req):
-        fn = FormFn(self.xd.domain_mem_target_set,
-                    [['dom',    'int'],
-                     ['target', 'int']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return val
+        return self.call(self.dom.setMemoryTarget
+                         [['target', 'int']],
+                         req)
 
     def op_devices(self, op, req):
-        fn = FormFn(self.xd.domain_devtype_ls,
-                    [['dom',    'int'],
-                     ['type',   'str']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return val
+        return self.call(self.dom.getDeviceSxprs,
+                         [['deviceClass', 'str']],
+                         req)
 
     def op_device_create(self, op, req):
-        fn = FormFn(self.xd.domain_device_create,
-                    [['dom',    'int'],
-                     ['config', 'sxpr']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return val
+        return self.call(self.dom.device_create,
+                         [['dev_config', 'sxpr']],
+                         req)
 
     def op_device_destroy(self, op, req):
-        fn = FormFn(self.xd.domain_device_destroy,
-                    [['dom',  'int'],
-                     ['type', 'str'],
-                     ['dev',  'str']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return val
+        return self.call(self.dom.destroyDevice,
+                         [['deviceClass', 'str'],
+                          ['devid',       'int']],
+                         req)
                 
     def op_device_configure(self, op, req):
-        fn = FormFn(self.xd.domain_device_configure,
-                    [['dom',    'int'],
-                     ['config', 'sxpr'],
-                     ['dev',    'str']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return val
+        return self.call(self.dom.device_configure,
+                         [['dev_config', 'sxpr'],
+                          ['devid',       'int']],
+                         req)
+
 
     def op_vif_limit_set(self, op, req):
         fn = FormFn(self.xd.domain_vif_limit_set,
@@ -182,12 +166,10 @@ class SrvDomain(SrvDir):
         return val
 
     def op_vcpu_hotplug(self, op, req):
-        fn = FormFn(self.xd.domain_vcpu_hotplug,
-                    [['dom', 'int'],
-                     ['vcpu', 'int'],
-                     ['state', 'int']])
-        val = fn(req.args, {'dom': self.dom.domid})
-        return val
+        return self.call(self.dom.vcpu_hotplug,
+                         [['vcpu', 'int'],
+                          ['state', 'int']],
+                         req)
 
     def render_POST(self, req):
         return self.perform(req)
@@ -201,7 +183,6 @@ class SrvDomain(SrvDir):
         #
         # if op and op[0] in ['vifs', 'vif', 'vbds', 'vbd', 'mem_target_set']:
         #    return self.perform(req)
-        self.dom.update()
         if self.use_sxp(req):
             req.setHeader("Content-Type", sxp.mime_type)
             sxp.show(self.dom.sxpr(), out=req)
index 0bbcd8e607c8206de5537978972494e97466f9ca..b410174facbed4eae31c179ff4026a8634da466c 100644 (file)
@@ -22,6 +22,7 @@ from xen.web import http
 
 from xen.xend import sxp
 from xen.xend import XendDomain
+from xen.xend.XendDomainInfo import XendDomainInfo
 from xen.xend.Args import FormFn
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
@@ -29,6 +30,7 @@ from xen.xend.XendLogging import log
 from xen.web.SrvDir import SrvDir
 from SrvDomain import SrvDomain
 
+
 class SrvDomainDir(SrvDir):
     """Service that manages the domain directory.
     """
@@ -124,28 +126,41 @@ class SrvDomainDir(SrvDir):
             out.close()
             return val
 
+
+    def op_list(self, _, req):
+        """List the details for this domain."""
+        self._list(req, True)
+
+
     def render_POST(self, req):
         return self.perform(req)
 
     def render_GET(self, req):
+        self._list(req, 'detail' in req.args and req.args['detail'] == ['1'])
+
+
+    def _list(self, req, detail):
         if self.use_sxp(req):
             req.setHeader("Content-Type", sxp.mime_type)
-            self.ls_domain(req, 1)
+            self.ls_domain(req, detail, True)
         else:
             req.write("<html><head></head><body>")
             self.print_path(req)
             self.ls(req)
-            self.ls_domain(req)
+            self.ls_domain(req, detail, False)
             self.form(req)
             req.write("</body></html>")
 
-    def ls_domain(self, req, use_sxp=0):
+
+    def ls_domain(self, req, detail, use_sxp):
         url = req.prePathURL()
         if not url.endswith('/'):
             url += '/'
         if use_sxp:
-            domains = self.xd.list_names()
-            sxp.show(domains, out=req)
+            if detail:
+                sxp.show(map(XendDomainInfo.sxpr, self.xd.list()), out=req)
+            else:
+                sxp.show(self.xd.list_names(), out=req)
         else:
             domains = self.xd.list_sorted()
             req.write('<ul>')
@@ -158,6 +173,7 @@ class SrvDomainDir(SrvDir):
                 req.write('</li>')
             req.write('</ul>')
 
+
     def form(self, req):
         """Generate the form(s) for domain dir operations.
         """
index 8433d819daddd847542ea02d6a229485755bbc8c..615ef4ef6072a478ec96608950f38fb72276b3f0 100644 (file)
@@ -225,25 +225,22 @@ def xm_list(args):
         if k in ['-v', '--vcpus']:
             show_vcpus = 1
 
-    domsinfo = []
     from xen.xend.XendClient import server
     if n == 0:
-        doms = server.xend_domains()
-        doms.sort()
+        doms = server.xend_list_domains()
     else:
-        doms = params
-    for dom in doms:
-        info = server.xend_domain(dom)
-        domsinfo.append(parse_doms_info(info))
+        doms = map(server.xend_domain, params)
                
     if use_long:
         for dom in doms:
-            info = server.xend_domain(dom)
-            PrettyPrint.prettyprint(info)
-    elif show_vcpus:
-        xm_show_vcpus(domsinfo)
+            PrettyPrint.prettyprint(doms)
     else:
-        xm_brief_list(domsinfo)
+        domsinfo = map(parse_doms_info, doms)
+
+        if show_vcpus:
+            xm_show_vcpus(domsinfo)
+        else:
+            xm_brief_list(domsinfo)
 
 def parse_doms_info(info):
     dominfo = {}
@@ -279,12 +276,12 @@ def parse_doms_info(info):
     return dominfo
         
 def xm_brief_list(domsinfo):
-    print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)'
+    print 'Name              ID  Mem(MiB)  CPU  VCPUs  State   Time(s)'
     for dominfo in domsinfo:
         if dominfo.has_key("ssidref1"):
-            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo)
+            print ("%(name)-16s %(dom)3d  %(mem)8d  %(cpu)3s  %(vcpus)5d  %(state)5s  %(cpu_time)7.1f     s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo)
         else:
-            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f" % dominfo)
+            print ("%(name)-16s %(dom)3d  %(mem)8d  %(cpu)3s  %(vcpus)5d  %(state)5s  %(cpu_time)7.1f" % dominfo)
 
 def xm_show_vcpus(domsinfo):
     print 'Name              Id  VCPU  CPU  CPUMAP'